<template>
  <div class="app-container">
    <v-row :gutter="20">
      <!-- 部门搜索 -->
      <v-col md="2">
        <!-- 请输入部门名称 -->
        <div class="head-container">
          <v-text-field
            dense
            solo
            v-model="deptName"
            placeholder="filter未实现"
            clearable
            prepend-inner-icon="mdi-magnify"
            style="width: 240px;"
          ></v-text-field>
        </div>
        <!-- 部门数据 -->
        <!-- 树形数据结构-->
        <div class="head-container">
          <v-treeview v-if="deptOptions"
                      ref="tree"
                      dense
                      activatable
                      color="warning"
                      open-all
                      hoverable
                      :search="deptName"
                      :filter="filterNode"
                      :items="deptOptions" style="font-size: 14px;padding: 0;"
          >
            <!-- 插槽 -->
            <template v-slot:prepend="{ item, open }">
              <div @click="handleNodeClick(item)">
                {{item.label}}
              </div>
            </template>
          </v-treeview>
        </div>
      </v-col>

      <!-- 用户 -->
      <v-col>
        <v-form ref="queryForm" v-show="showSearch" label-width="68px">
          <v-row>
            <v-col md="2" style="padding-bottom: 2px">
              <v-text-field
                label="用户名称"
                v-model="queryParams.userName"
                placeholder="请输入用户名称"
                outlined
                dense
                clearable
                @keyup.enter.native="handleQuery"
                style="width: 240px;"
              ></v-text-field>
            </v-col>
            <v-col md="2" style="padding-bottom: 2px">
              <v-text-field
                label="手机号码"
                v-model="queryParams.phonenumber"
                placeholder="请输入手机号码"
                outlined
                dense
                style="width: 240px;"
                @keyup.enter.native="handleQuery"
              ></v-text-field>
            </v-col>
            <v-col md="2" style="padding-bottom: 2px;max-width: 150px">
              <v-select
                label="状态"
                v-model="queryParams.status"
                :items="statusOptions"
                item-text="dictLabel"
                item-value="dictValue"
                dense
                outlined
                clearable
                style="width: 130px;"
              ></v-select>
            </v-col>
            <v-col cols="12"
                   sm="6"
                   md="2" style="padding-bottom: 2px;max-width: 180px">
              <v-menu
                ref="dateRangeMenu"
                v-model="dateRangeMenu"
                :close-on-content-click="false"
                transition="scale-transition"
                offset-y
                max-width="240px"
                min-width="auto"
                style="width: 240px;padding-top: 0;margin-top: 0"
              >
                <template v-slot:activator="{ on, attrs }">
                  <v-text-field
                    v-model="date"
                    label="创建时间"
                    prepend-icon="mdi-calendar"
                    v-bind="attrs"
                    @blur="date = parseDate(dateFormatted)"
                    v-on="on"
                    clearable
                    style="width: 240px;padding-top: 0"
                  ></v-text-field>
                </template>
                <v-date-picker
                  v-model="date"
                  no-title
                  @input="dateRangeMenu = false"
                  style="padding: 0"
                ></v-date-picker>
              </v-menu>
            </v-col>

            <!-- 按钮区-->
            <v-col cols="12"
                   sm="6"
                   md="2" style="padding-bottom: 0;margin-left: 1rem;height: 40px;margin-top: 8px">
              <p style="display: inline-block;position: absolute">
                <v-btn
                  small color="primary"
                  :loading="loading"
                  @click="handleQuery">
                  <v-icon left>
                    mdi-magnify
                  </v-icon>
                  搜索
                </v-btn>
                <v-btn
                  small
                  :loading="loading"
                  @click="resetQuery"
                  style="margin-left: 10px"
                >
                  <v-icon left>
                    mdi-autorenew
                  </v-icon>
                  重置
                </v-btn>
              </p>
            </v-col>
          </v-row>
        </v-form>

        <!-- 表格操作按钮区 -->
        <v-row style="margin-bottom: -5px">
          <v-col md="1" style="max-width: 84px">
            <v-btn
              color="primary"
              plain
              small
              outlined
              @click="handleAdd"
              v-hasPermi="['system:user:add']">
              <v-icon left>
                mdi-plus
              </v-icon>
              新增
            </v-btn>
          </v-col>
          <v-col md="1" style="max-width: 84px">
            <v-btn
              small
              plain
              outlined
              :disabled="single"
              @click="handleUpdate(ids[0])"
              v-hasPermi="['system:user:edit']">
              <v-icon left>
                mdi-pencil
              </v-icon>
              修改
            </v-btn>
          </v-col>
          <!--todo 二次确认删除按钮 -->
          <v-col md="1" style="max-width: 84px">
            <v-btn
              small color="error"
              plain
              outlined
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:user:remove']">
              <v-icon left>
                mdi-delete
              </v-icon>
              删除
            </v-btn>
          </v-col>
          <v-col md="1" style="max-width: 84px">
            <v-btn
              small
              plain
              outlined
              @click="handleImport"
              v-hasPermi="['system:user:import']">
              <v-icon left>
                mdi-download
              </v-icon>
              导入
            </v-btn>
          </v-col>
          <v-col md="1" style="max-width: 84px">
            <v-btn
              type="warning"
              small
              plain
              outlined
              @click="handleExport"
              v-hasPermi="['system:user:export']">
              <v-icon left>
                mdi-upload
              </v-icon>
              导出
            </v-btn>
          </v-col>
          <v-col style="float: right">
            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
          </v-col>
        </v-row>

        <!-- 表格-->
        <v-main>
          <v-data-table v-if="userList"
              v-model="ids"
              :headers="headers"
              :items="userList"
              :items-per-page="queryParams.pageSize"
              hide-default-footer
              :loading="loading"
              loading-text="加载中,请稍后.."
              show-select
              item-key="userId"
              class="elevation-1"
              no-data-text="暂无数据"
          >
            <!-- 状态插槽 -->
            <template v-slot:item.status="{ item }">
              <div v-if="item.status === '1'">正常</div>
              <div v-if="item.status === '0'" style="color: red">停用</div>
              <!--<v-switch-->
              <!--  input-value="1"-->
              <!--  v-model="item.status === '1'"-->
              <!--  flat dense-->
              <!--  @change="handleStatusChange(item)"-->
              <!--  :label="item.status === '1' ? '正常' : '停用'" style="padding: 0;margin: 0;text-align: center;padding-left: 20px"-->
              <!--&gt;</v-switch>-->
            </template>

            <!-- 按钮插槽 -->
            <template v-slot:item.actions="{ item }">
              <v-btn text
                     small
                     plain
                     height="20"
                     width="40"
                     @click="handleUpdate(item)"
                     v-hasPermi="['system:user:edit']">
                <v-icon small>
                  mdi-pencil
                </v-icon>
                修改
              </v-btn>
              <!-- 删除确认 -->
              <span v-if="item && !item.showConfirmDelete">
                <v-btn color="#C62828"
                       small
                       plain
                       height="20"
                       width="40"
                       @click="onClickDelete(item)">
                  <v-icon small>
                    mdi-delete
                  </v-icon>
                  删除
                </v-btn>
              </span>
              <span v-else>
                <v-tooltip top>
                  <template v-slot:activator="{ on, attrs }">
                    <v-btn
                      small color="error"
                      plain
                      height="20"
                      width="40"
                      v-bind="attrs"
                      v-on="on"
                      @click="handleDelete(item)"
                      v-hasPermi="['system:user:remove']">
                      <v-icon small>
                        mdi-delete
                      </v-icon>
                      确定
                    </v-btn>
                  </template>
                  <span>请再次点击确定删除</span>
                </v-tooltip>
              </span>
              <!-- todo 重置密码按钮 -->
            </template>
          </v-data-table>
          <!-- 外部分页-->
          <div class="d-flex align-center justify-end text-center">
            <div class="d-flex" style="margin-top: 3px;font-size: 14px;font-weight: 400">
              <span>每页</span>
              <v-select
                v-model="queryParams.pageSize"
                :items="numbers"
                dense
                @change="getList" style="max-width: 80px;max-height: 20px;margin-top: -4px;text-align: center;">
                <template v-slot:selection="{ item, index }">
                  <span style="width: 100%">
                    {{item}}
                  </span>
                </template>
              </v-select>
              <span>条记录</span>
            </div>
            <v-pagination
              v-model="queryParams.pageNum"
              @input="getList"
              :length="queryParams.totalPages"
              :total-visible="7"
            ></v-pagination>
          </div>
        </v-main>
      </v-col>
    </v-row>

    <!-- 用户导入对话框 -->
    <v-dialog
      v-model="upload.open" max-width="400px" persistent transition="dialog-top-transition">
      <v-card>
        <v-card-title>
          <span style="font-size: 16px;padding: 0;">用户导入</span>
        </v-card-title>
        <v-row justify="center" style="width: 100%;margin: 0 auto">
          <el-upload
            ref="upload"
            :limit="1"
            accept=".xlsx, .xls"
            :headers="upload.headers"
            :action="upload.url + '?updateSupport=' + upload.updateSupport"
            :disabled="upload.isUploading"
            :on-progress="handleFileUploadProgress"
            :on-success="handleFileSuccess"
            :auto-upload="false"
            drag
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              将文件拖到此处，或
              <em>点击上传</em>
            </div>
            <div class="el-upload__tip" slot="tip">
              <el-checkbox v-model="upload.updateSupport" style="margin-right: 5px"/>是否更新已经存在的用户数据
              <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
            </div>
            <div class="el-upload__tip" style="color:red" slot="tip">提示：仅允许导入“xls”或“xlsx”格式文件！</div>
          </el-upload>
        </v-row>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            text
            @click="upload.open = false">
            取消
          </v-btn>
          <v-btn
            color="blue darken-1"
            text
            @click="submitFileForm">
            确定
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- 新增用户 -->
    <user-add ref="userEditFormRef" :visible="showAdd" @updateVisible="updateVisible" @done="handleQuery" :sexOptions="sexOptions" :deptOptions="deptOptions"
                                 :statusOptions="statusOptions" :postOptions="postOptions" :roleOptions="roleOptions"></user-add>
    <!-- 修改用户 -->
    <user-edit ref="userEditFormRef" :visible="showEdit" @updateVisible="updateVisible" :data="form" @done="handleQuery" :sexOptions="sexOptions" :deptOptions="deptOptions"
              :statusOptions="statusOptions" :postOptions="postOptions" :roleOptions="roleOptions"></user-edit>
  </div>
</template>

<script>
  import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
  import { getToken } from "@/utils/auth";
  import { treeselect } from "@/api/system/dept";
  import Treeselect from "@riophae/vue-treeselect";
  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  import userAdd from "@/views/system/user/userAdd"; // 用户新增对话框
  import userEdit from "@/views/system/user/userEdit"; // 用户修改对话框

  export default {
    name: "User",
    components: { Treeselect, userAdd, userEdit },
    data() {
      return {
        // 是否显示弹出层
        edit: false,
        showAdd: false,
        showEdit: false,
        // 遮罩层
        loading: true,
        // 选中数组
        ids: [],
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        // 显示搜索条件
        showSearch: true,
        // 总条数
        total: 0,
        // 用户表格数据
        userList: null,
        // 弹出层标题
        title: "",
        // 部门树选项
        deptOptions: undefined,
        // 部门名称
        deptName: undefined,
        // 默认密码
        initPassword: undefined,
        // 日期范围
        dateRange: [],
        // 状态数据字典
        statusOptions: [],
        // 性别状态字典
        sexOptions: [],
        // 岗位选项
        postOptions: [],
        // 角色选项
        roleOptions: [],
        // 表单参数
        form: {},
        defaultProps: {
          children: "children",
          label: "label"
        },
        // 用户导入参数
        upload: {
          // 是否显示弹出层（用户导入）
          open: false,
          // 弹出层标题（用户导入）
          title: "",
          // 是否禁用上传
          isUploading: false,
          // 是否更新已经存在的用户数据
          updateSupport: 0,
          // 设置上传的请求头部
          headers: { Authorization: "Bearer " + getToken() },
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + "/system/user/importData"
        },
        // v-table 表格头
        headers: [
          { text: '用户编号', value: 'userId', align: 'center' },
          { text: '用户名称', value: 'userName', align: 'center' },
          { text: '用户昵称', value: 'nickName', align: 'center' },
          { text: '部门', value: 'dept.deptName', sortable: false, align: 'center' },
          { text: '手机号码', value: 'phonenumber', sortable: false, align: 'center' },
          { text: '状态', value: 'status', sortable: false, align: 'center' },
          { text: '操作', value: 'actions', sortable: false, align: 'center' },
        ],
        options: {}, // v-table
        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          totalPages: 0, // 总页数
          userName: undefined,
          phonenumber: undefined,
          status: undefined,
          deptId: undefined,
        },
        // 列信息
        columns: [
          { key: 0, label: `用户编号`, visible: true },
          { key: 1, label: `用户名称`, visible: true },
          { key: 2, label: `用户昵称`, visible: true },
          { key: 3, label: `部门`, visible: true },
          { key: 4, label: `手机号码`, visible: true },
          { key: 5, label: `状态`, visible: true },
          { key: 6, label: `创建时间`, visible: true }
        ],
        // 表单校验
        rules: {
          userName: [
            { required: true, message: "用户名称不能为空", trigger: "blur" }
          ],
          nickName: [
            { required: true, message: "用户昵称不能为空", trigger: "blur" }
          ],
          password: [
            { required: true, message: "用户密码不能为空", trigger: "blur" }
          ],
          email: [
            {
              type: "email",
              message: "'请输入正确的邮箱地址",
              trigger: ["blur", "change"]
            }
          ],
          phonenumber: [
            {
              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
              message: "请输入正确的手机号码",
              trigger: "blur"
            }
          ]
        },
        caseSensitive: false,
        numbers: [10, 15, 20, 50, 100], // 每页条数选择
        dateRangeMenu: false,
        date: null,
        dateFormatted: this.formatDate((new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10)),
      };
    },
    watch: {
      // 根据名称筛选部门树
      deptName(val) {
        this.$refs.tree.filter(val);
      },
      date (val) {
        this.dateFormatted = this.formatDate(this.date)
      },
      ids() {
        this.handleSelectionChange();
      }
    },
    created() {
      this.getList();
      this.getTreeselect();
      this.getDicts("sys_normal_disable").then(response => {
        this.statusOptions = response.data;
      });
      this.getDicts("sys_user_sex").then(response => {
        this.sexOptions = response.data;
      });
      this.getConfigKey("sys.user.initPassword").then(response => {
        this.initPassword = response.msg;
      });
    },
    methods: {
      // 查询用户列表 v-table 服务器端分页查询
      getList() {
        this.ids = [];
        this.loading = true;
        // todo 日期范围
        //listUser(this.addDateRange(this.queryParams, this.data)).then(response => {
        listUser(this.queryParams).then(response => {
          this.userList = response.rows;
          //for (let i = 0; i < this.userList.length; i++) {
          //  this.$set(this.userList[i], 'showConfirmDelete', false);
          //}
          this.total = response.total;
          // 总页数
          this.queryParams.totalPages = Math.ceil(this.total / this.queryParams.pageSize);
          this.loading = false;
        });
      },
      /** 查询部门下拉树结构 */
      getTreeselect() {
        treeselect().then(response => {
          this.deptOptions = response.data;
        });
      },
      // 筛选节点
      filterNode(value, data) {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
      },
      // 节点单击事件
      handleNodeClick(data) {
        this.queryParams.deptId = data.id;
        this.getList();
      },
      // 用户状态修改
      handleStatusChange(row) {
        var that = this;
        let text = row.status === "0" ? "启用" : "停用";
        this.$confirm('确认要"' + text + '""' + row.userName + '"用户吗?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(function() {
          return changeUserStatus(row.userId, row.status === "0" ? '1' : '0');
        }).then(() => {
          this.getList();
          this.msgSuccess(text + "成功");
        }).catch(function() {
          that.getList();
          row.status = row.status === "0" ? "1" : "0";
        });
      },
      // 取消按钮
      cancel() {
        this.open = false;
        this.reset();
      },
      // 表单重置
      reset() {
        this.form = {
          userId: undefined,
          deptId: undefined,
          userName: undefined,
          nickName: undefined,
          password: undefined,
          phonenumber: undefined,
          email: undefined,
          sex: undefined,
          status: "0",
          remark: undefined,
          postIds: [],
          roleIds: []
        };
        this.resetForm("form");
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParams.page = 1;
        if (this.date) {
          this.queryParams.createTime = this.date;
        } else {
          this.queryParams.createTime = null;
        }
        this.getList();
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.dateRange = [];
        this.$refs.queryForm.reset(); // 重置
        this.handleQuery();
      },
      // 多选框选中数据
      handleSelectionChange() {
        this.single = this.ids.length !== 1;
        this.multiple = !this.ids.length;
      },
      /** 新增按钮操作 */
      handleAdd() {
        this.reset();
        this.getTreeselect();
        getUser().then(response => {
          this.postOptions = response.posts;
          this.roleOptions = response.roles;
          this.form.password = this.initPassword;
          this.showAdd = true;
        });
      },
      /** 修改按钮操作 */
      handleUpdate(row) {
        this.getTreeselect();
        const userId = row.userId || this.ids;
        getUser(userId).then(response => {
          let temp = response.data;
          temp.postIds = response.postIds;
          temp.roleIds = response.roleIds;
          this.postOptions = response.posts;
          this.roleOptions = response.roles;
          this.form = Object.assign({}, temp)
          this.showEdit = true;
        });
      },
      /** 重置密码按钮操作 */
      handleResetPwd(row) {
        this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消"
        }).then(({ value }) => {
          resetUserPwd(row.userId, value).then(res => {
            this.msgSuccess("修改成功，新密码是：" + value);
          });
        }).catch(() => {});
      },
      updateVisible(value) {
        this.showAdd = value;
        this.showEdit = value;
      },
      // 表格列点击删除按钮，切换确定删除按钮
      onClickDelete(item) {
        this.$set(item, 'showConfirmDelete', true);
        setTimeout(() => {
          this.$set(item, 'showConfirmDelete', false);
        }, 3500);
      },
      /** 删除按钮操作 */
      async handleDelete() {
        this.$store.commit("snackbar/CLOSE_SNACKBAR");
        const userIds = this.ids.map(item => item.userId);
        await delUser(userIds).then(res => {
          if (res) {
            // 使用全局消息提示
            this.$store.dispatch('snackbar/openSnackbar', {
              msg: '删除成功',
              color: 'success'
            })
            this.getList();
          }
        });
      },
      /** 导出按钮操作 */
      handleExport() {
        this.download('system/user/export', {
          ...this.queryParams
        }, `user_${new Date().getTime()}.xlsx`)
      },
      /** 导入按钮操作 */
      handleImport() {
        this.upload.title = "用户导入";
        this.upload.open = true;
      },
      /** 下载模板操作 */
      importTemplate() {
        this.download('system/user/importTemplate', {
          ...this.queryParams
        }, `user_${new Date().getTime()}.xlsx`)
      },
      // 文件上传中处理
      handleFileUploadProgress(event, file, fileList) {
        this.upload.isUploading = true;
      },
      // 文件上传成功处理
      handleFileSuccess(response, file, fileList) {
        this.upload.open = false;
        this.upload.isUploading = false;
        this.$refs.upload.clearFiles();
        this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
        this.getList();
      },
      // 提交上传文件
      submitFileForm() {
        this.$refs.upload.submit();
      },
      // 创建时间 日期格式化
      formatDate (date) {
        if (!date) return null
        const [year, month, day] = date.split('-')
        return `${month}/${day}/${year}`
      },
      parseDate (date) {
        if (!date) return null
        const [month, day, year] = date.split('/')
        return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
      },
    }
  };
</script>
